package io.jenkins.plugins.feishu;

import hudson.Extension;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import io.jenkins.plugins.feishu.service.FeishuService;
import java.io.Serial;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
import org.jenkinsci.plugins.workflow.steps.StepExecution;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.springframework.lang.NonNull;

public class FeishuStep extends Step {
    private static final Logger LOG = Logger.getLogger(FeishuNotifier.class.getName());
    private String webHookUrl;
    private String message;
    private String color;
    private String title;

    @DataBoundConstructor
    public FeishuStep(String webHookUrl,  String color, String title, String message) {
        this.webHookUrl = webHookUrl;
        this.message = message;
        this.color = color;
        this.title = title;
    }

    public String getWebHookUrl() {
        return webHookUrl;
    }

    @DataBoundSetter
    public void setWebHookUrl(String webHookUrl) {
        this.webHookUrl = webHookUrl;
    }

    public String getMessage() {
        return message;
    }

    @DataBoundSetter
    public void setMessage(String message) {
        this.message = message;
    }

    public String getColor() {
        return color;
    }

    @DataBoundSetter
    public void setColor(String color) {
        this.color = color;
    }

    public String getTitle() {
        return title;
    }

    @DataBoundSetter
    public void setTitle(String title) {
        this.title = title;
    }

    @Override
    public StepExecution start(StepContext context) throws Exception {
        return new FeishuStepExecution(this, context);
    }

    private static class FeishuStepExecution extends StepExecution {
        @Serial
        private static final long serialVersionUID = 1L;

        private final transient FeishuStep step;

        private FeishuStepExecution(FeishuStep step, StepContext context) {
            super(context);
            this.step = step;
        }

        private boolean isEmpty(String s) {
            return s == null || s.trim().isEmpty();
        }

        @Override
        public boolean start() throws Exception {
            StepContext context = this.getContext();
            LOG.info("Send feishu message.");

            try {
                Run<?, ?> run = getContext().get(Run.class);
                TaskListener listener = context.get(TaskListener.class);
                String jenkinsUrl = Jenkins.get().getRootUrl() + run.getConsoleUrl();
                String jobName = run.getParent().getDisplayName();
                long startTimeInMillis = run.getStartTimeInMillis();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String startTime = sdf.format(new Date(startTimeInMillis));
                long duration = run.getDuration();
                String content = "流水线名称: " + jobName  +"\\n发布时间: " + startTime + "\\n耗时: " + duration + "ms";
                String msg = step.getMessage();
                if(!isEmpty(msg)){
                    content = msg;
                }
                String wb = step.getWebHookUrl();
                String color = step.getColor();
                String title = step.getTitle();
                FeishuService client = new FeishuService(wb);
                client.send(color, title, content, jenkinsUrl);
                listener.getLogger().println("webhook发送通知成功.");

                // 必须调用onSuccess或onFailure
                context.onSuccess(null);
                return true;
            } catch (Exception e) {
                context.onFailure(e);
                return false;
            }
        }
    }

    @Extension
    public static class DescriptorImpl extends StepDescriptor implements Serializable {

        public DescriptorImpl() {}

        @Override
        public Set<? extends Class<?>> getRequiredContext() {
            return new HashSet<>() {
                {
                    add(Run.class);
                    add(TaskListener.class);
                }
            };
        }


        @Override
        public String getFunctionName() {
            return "FeishuNotify";
        }

        @NonNull
        @Override
        public String getDisplayName() {
            return "Send Feishu message";
        }
    }
}
